/*
 * Copyright (c) 2022, Chongqing UCchip InfoTech Co.,Ltd
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-12-19     jlu          the first version
 */
#include "net_app.h"
#include "config_boot.h"
#include "config_api.h"
#include "gateway_manager.h"
#include "led_manager.h"
#include "manager_task.h"
#include "manager_queue.h"
#include "manager_queue_comm.h"
#include "module_queue_struct.h"
#include "interaction_manager.h"
#include "net_down.h"
#include "net_mqtt.h"
#include "net_prot.h"
#include "netdev_manager.h"
#include "ota_manager.h"
#include "state_manager.h"
#include "transparent_protocol.h"
#include "uc_coding.h"
#include "netdev_manager.h"
#include "json_to_data.h"
#include "serial_app.h"
#include <netdev_ipaddr.h>
#include <netdev.h>
#include <rthw.h>
#include <rtthread.h>
#include <ipc/workqueue.h>

#define DBG_ENABLE
#define DBG_SECTION_NAME "net_app"
#include "uc_log.h"

void *g_test_mem_one = RT_NULL;
void *g_test_mem_two = RT_NULL;

// push的数据计数开关宏
#define PUSH_DATA_COUNT_ENABLE
/**
 * @brief net_app 消息队列
 *
 */
static void *g_net_app_queue = RT_NULL;
static void *g_net_change_app_queue = RT_NULL;

static unsigned char g_net_status_change_send_flag = RT_FALSE;

unsigned int g_mqtt_offline_time = (~0);

/**
 * @brief  创建 net_app 消息队列
 *
 * @return 成功返回0，否则返回非0
 */
int net_app_create_queue(void)
{
    g_net_app_queue = manager_create_queue("net_app", 4, 100, UC_SYSTEM_IPC_FLAG_PRIO);
    if (RT_NULL == g_net_app_queue)
    {
        TRACE_E("manager_create_queue error in %s line %d", __FUNCTION__, __LINE__);
        return 1;
    }
    return 0;
}

/**
 * @brief  创建 net_change_app 消息队列
 *
 * @return 成功返回0，否则返回非0
 */
int net_change_app_create_queue(void)
{
    g_net_change_app_queue = manager_create_queue("net_app_change", 4, 100, UC_SYSTEM_IPC_FLAG_PRIO);
    if (RT_NULL == g_net_change_app_queue)
    {
        TRACE_E("manager_create_queue error in %s line %d", __FUNCTION__, __LINE__);
        return 1;
    }
    return 0;
}

/**
 * @brief  获取 net_app 消息队列
 *
 * @return net_app 消息队列
 */
void *net_app_get_queue(void)
{
    return g_net_app_queue;
}

/**
 * @brief  获取 net_change_app 消息队列
 *
 * @return net_change_app 消息队列
 */
void *get_net_change_app_queue(void)
{
    return g_net_change_app_queue;
}

/**
 * @brief  通知网卡切换
 *
 * @return 发送网卡切换消息
 */
void notifice_netdev_change(void)
{
    module_queue_communication(module_get_queue(NET_CHANGE_APP_MODULE),
                               NET_APP_MODULE,
                               NET_CHANGE_APP_MODULE,
                               NETDEV_CHANGE_CMD,
                               RT_NULL);
}

/**
 * @brief  MQTT 发送消息
 *
 * @param  state 状态
 */
static int net_publish(char *payload)
{
    int res = 0;
    if (RT_NULL != payload)
    {
#ifdef MQTT_PACKET_GROUP
        res = write_mqtt_data(payload, rt_strlen(payload));
        // res = manager_send_queue(mqtt_com_get_queue(), payload, MODULE_SEND_QUEUE_TIMEOUT);
        if (RT_EOK != res)
        {
            TRACE_E("write_mqtt_data error in %s line %d res=%d", __FUNCTION__, __LINE__, res);
        }
        rt_free(payload);

        if (g_test_mem_one == payload)
        {
            g_test_mem_one = RT_NULL;
        }
        else if (g_test_mem_two == payload)
        {
            g_test_mem_two = RT_NULL;
        }

        payload = RT_NULL;
#else
        char *argv[] = {"mqtt_publish", payload};

        // 发布消息
        res = mqtt_publish(2, argv);
        if (0 != res)
        {
            TRACE_E("mqtt publish fail res %d", res);
            res = 1;
        }
        // 释放内存
        rt_free(payload);
        payload = RT_NULL;
        send_led_event(LED_MQTT, LED_E_BLINK);
#endif
    }
    else
    {
        res = 2;
    }

    return res;
}

/**
 * @brief  IOTE 状态更新
 *
 * @param  state 状态
 */
static void net_iote_state_update(void *state)
{
    if (RT_NULL != state)
    {
        net_publish(encode_iote_state(state));
        mng_ul_iote_state_free((mng_ul_iote_state_t *)state);
    }
}

/**
 * @brief  IOTE版本查询响应
 *
 * @param  iote_ver 终端版本
 */
static void net_iote_version_res(void *iote_ver)
{
    if (RT_NULL != iote_ver)
    {
        net_publish(encode_iote_version_response(iote_ver));
    }
}

/**
 * @brief  用户数据上报
 *
 * @param  user_data 用户数据
 */
static void net_iote_user_data(void *user_data)
{
    if (RT_NULL != user_data)
    {
#ifdef PUSH_DATA_COUNT_ENABLE
        static int send_data_count = 0;
        int push_res = 0;
#endif

        push_res = net_publish(encode_user_data(user_data));
        mng_ul_userdata_free((mng_ul_userdata_t *)user_data);
#ifdef PUSH_DATA_COUNT_ENABLE
        send_data_count++;
        TRACE_D("send count %d", send_data_count);
#endif
    }
}

/**
 * @brief  发送用户数据
 *
 * @param  user_data 用户数据
 * @param  cmd wiota命令
 * @return 成功放回0，否则返回非0
 */
static int send_user_data(net_dl_userdata_t *user_data, int cmd)
{
    if (RT_NULL == user_data)
    {
        return 1;
    }
    void *queue = get_gateway_manager_queue();
    // 发送用户数据
    if (RT_NULL == queue || module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, cmd, (void *)user_data))
    {
        net_dl_userdata_free(user_data);
        return 2;
    }
    return 0;
}

/**
 * @brief  发送485透传数据
 *
 * @param  transparent_data 透传数据
 * @param  cmd wiota命令
 * @return 成功放回0，否则返回非0
 */
static int send_transparent_data(net_dl_transparent_data_t *transparent_data, int cmd)
{
    if (RT_NULL == transparent_data)
    {
        return 1;
    }
    void *queue = get_serial_queue();
    // 发送用户数据
    if (RT_NULL == queue || module_queue_communication(queue, NET_APP_MODULE, SERIAL_485_MANAGER_MODULE, cmd, (void *)transparent_data))
    {
        net_dl_transparent_data_free(transparent_data);
        return 2;
    }
    return 0;
}

/**
 * @brief  设置配置参数
 *
 * @param  param 参数
 * @return 成功放回0，否则返回非0
 */
static int set_config(net_cfg_set_t *param)
{
    if (RT_NULL == param)
    {
        return 1;
    }

    void *queue = get_gateway_manager_queue();
    if (RT_NULL != queue)
    {
        if (RT_NULL != param->sys_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_SYS_CFG_SET, (void *)param->sys_cfg))
                rt_free(param->sys_cfg);
        }
        if (RT_NULL != param->act_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_ACT_CFG_SET, (void *)param->act_cfg))
                rt_free(param->act_cfg);
        }
        if (RT_NULL != param->freq_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_FREQ_CFG_SET, (void *)param->freq_cfg))
                rt_free(param->freq_cfg);
        }
        if (RT_NULL != param->power_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_POWER_CFG_SET, (void *)param->power_cfg))
                rt_free(param->power_cfg);
        }
        if (RT_NULL != param->rate_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_RATE_CFG_SET, (void *)param->rate_cfg))
                rt_free(param->rate_cfg);
        }
        if (RT_NULL != param->paging_tx_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_PAGING_TX_CFG_SET, (void *)param->paging_tx_cfg))
            {
                // param->paging_tx_cfg不为空时param->paging_tx_cfg->paging_tx一定不为空
                rt_free(param->paging_tx_cfg->paging_tx);
                if (param->paging_tx_cfg->user_data)
                {
                    rt_free(param->paging_tx_cfg->user_data);
                }
                rt_free(param->paging_tx_cfg);
            }
        }
        if (RT_NULL != param->sync_paging_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_SYNC_PAGING_CFG_SET, (void *)param->sync_paging_cfg))
                rt_free(param->sync_paging_cfg);
        }
        if (RT_NULL != param->ts_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_TS_CFG_SET, (void *)param->ts_cfg))
                rt_free(param->ts_cfg);
        }
#ifdef WIOTA_SUBF_MODE_SUPPORT
        if (RT_NULL != param->subf_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIOTA_SUBF_MODE_CFG_SET, (void *)param->subf_cfg))
                rt_free(param->subf_cfg);
        }
#endif
        if (RT_NULL != param->base_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, GATEWAY_BASE_CFG_SET, (void *)param->base_cfg))
                rt_free(param->base_cfg);
        }
        if (RT_NULL != param->id_mng_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, ID_MANAGER_CFG_SET, (void *)param->id_mng_cfg))
                rt_free(param->id_mng_cfg);
        }
        if (RT_NULL != param->auth_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, AUTH_CFG_SET, (void *)param->auth_cfg))
                rt_free(param->auth_cfg);
        }
        if (RT_NULL != param->net_policy_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, NET_POLICY_CFG_SET, (void *)param->net_policy_cfg))
                rt_free(param->net_policy_cfg);
        }
        if (RT_NULL != param->net_if_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, NET_IF_CFG_SET, (void *)param->net_if_cfg))
                rt_free(param->net_if_cfg);
        }
        if (RT_NULL != param->wifi_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WIFI_CFG_SET, (void *)param->wifi_cfg))
                rt_free(param->wifi_cfg);
        }
        if (RT_NULL != param->cat1_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, CAT1_CFG_SET, (void *)param->cat1_cfg))
                rt_free(param->cat1_cfg);
        }
        if (RT_NULL != param->mqtt_server_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, MQTT_SERVER_CFG_SET, (void *)param->mqtt_server_cfg))
                rt_free(param->mqtt_server_cfg);
        }
        if (RT_NULL != param->data_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, DATA_CFG_SET, (void *)param->data_cfg))
                rt_free(param->data_cfg);
        }
        if (RT_NULL != param->wtd_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, WATCHDOG_CFG_SET, (void *)param->wtd_cfg))
                rt_free(param->wtd_cfg);
        }
        if (RT_NULL != param->log_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, GATEWAY_FTP_LOG_CFG_SET, (void *)param->log_cfg))
                rt_free(param->log_cfg);
        }
        if (RT_NULL != param->log_switch_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, LOG_SWITCH_CFG_SET, (void *)param->log_switch_cfg))
                rt_free(param->log_switch_cfg);
        }
        if (RT_NULL != param->uart_485_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, UART_485_CFG_SET, (void *)param->uart_485_cfg))
                rt_free(param->uart_485_cfg);
        }
        if (RT_NULL != param->timed_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, GATEWAY_TIMED_CFG_SET, (void *)param->timed_cfg))
                rt_free(param->timed_cfg);
        }
        if (RT_NULL != param->slot_send_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, SLOT_SEND_CFG_SET, (void *)param->slot_send_cfg))
                rt_free(param->slot_send_cfg);
        }
        if (RT_NULL != param->uboot_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, UBOOT_CFG_SET, (void *)param->uboot_cfg))
                rt_free(param->uboot_cfg);
        }
        if (RT_NULL != param->immediate_effective_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, IMMEDIATE_EFFECTIVE_SET, (void *)param->immediate_effective_cfg))
                rt_free(param->immediate_effective_cfg);
        }
        if (RT_NULL != param->sync_cfg)
        {
            if (module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, SYNC_CFG_SET, (void *)param->sync_cfg))
                rt_free(param->sync_cfg);
        }
    }

    rt_free(param);
    return 0;
}

/**
 * @brief  发送消息到管理线程
 *
 * @param  param       参数
 * @param  cmd         命令
 * @return 成功放回0，否则返回非0
 */
static int send_msg_to_mng(void *param, int cmd)
{
    void *queue = get_gateway_manager_queue();

    if (0 != module_queue_communication(queue, NET_APP_MODULE, GATEWAY_MANAGER_MODULE, cmd, param))
    {
        return 1;
    }
    return 0;
}

/**
 * @brief  MQTT 状态改变
 *
 * @param  state 状态
 */
static void net_mqtt_state_changed(int state)
{
    unsigned char get_info_state = manager_get_startup_info_state();

    if (state == MQTT_STATE_ONLINE)
    {
        // 网络连接成功后，将默认网卡信息更新到静态数据
        netdev_update_info();

        if (GET_INFO_WAIT == get_info_state)
        {
            module_queue_communication(module_get_queue(NET_APP_MODULE),
                                       NET_APP_MODULE,
                                       NET_APP_MODULE,
                                       ALL_CFG_GET,
                                       RT_NULL);
            manager_set_startup_info_state(GET_INFO_SUC);
        }
        else if (GET_INFO_SUC == get_info_state)
        {
            module_queue_communication(module_get_queue(GATEWAY_MANAGER_MODULE),
                                       NET_APP_MODULE,
                                       GATEWAY_MANAGER_MODULE,
                                       NET_CFG_GET,
                                       RT_NULL);
        }
    }
    else
    {
        notifice_netdev_change();
    }
}

/**
 * @brief  MQTT 收到消息
 *
 * @param  mqtt_msg 订阅消息
 */
static void net_mqtt_recv_msg(net_mqtt_message_t *mqtt_msg)
{
    unsigned int cmd = 0;

    // 解析主题 ID
    int id = parse_topic_id(mqtt_msg->topic, rt_strlen(mqtt_msg->topic));
    // 解析 JSON
    cJSON *root = cJSON_Parse(mqtt_msg->payload);
    if (RT_NULL != root)
    {
        // 解析命令
        parse_uint32(root, "cmd", &cmd);
        // TRACE_I("recv_msg cmd %d", cmd);
        switch (cmd)
        {
        case PROT_USER_DATA:
        case PROT_LOOP_DATA:
        case PROT_IOTE_VERSION_REQ:
        {
            if (cmd == PROT_USER_DATA)
            {
                TRACE_I("mqtt PROT_USER_DATA");
            }
            else if (cmd == PROT_LOOP_DATA)
            {
                TRACE_I("mqtt PROT_LOOP_DATA");
            }
            else
            {
                TRACE_I("mqtt PROT_IOTE_VERSION_REQ");
            }
            net_dl_userdata_t *user_data = (net_dl_userdata_t *)parse_user_data(root);
            if (RT_NULL != user_data)
            {
                if (0 != send_msg_to_mng(user_data, WIOTA_SEND_DATA))
                {
                    net_dl_userdata_free(user_data);
                }
            }
            break;
        }
        case PROT_TRANSPARENT_DATA:
        {
            TRACE_I("mqtt PROT_TRANSPARENT_DATA");
            net_dl_transparent_data_t *transparent_data = (net_dl_transparent_data_t *)parse_transparent_data(root);
            if (RT_NULL != transparent_data)
            {
                send_transparent_data(transparent_data, NET_RECV_TRANSPARENT_DATA);
            }
            break;
        }
        case PROT_SET_CONFIG:
            TRACE_I("mqtt PROT_SET_CONFIG");
            set_config((net_cfg_set_t *)parse_set_config(root));
            break;
        case PROT_QUERY_CONFIG:
            TRACE_I("mqtt PROT_QUERY_CONFIG");
            send_msg_to_mng(RT_NULL, parse_query_config(root));
            break;
        case PROT_EXEC_CONFIG:
            TRACE_I("mqtt PROT_EXEC_CONFIG");
            send_msg_to_mng(RT_NULL, parse_exec_config(root));
            break;
        case PROT_OTA_UPDATE:
        {
            TRACE_I("mqtt PROT_OTA_UPDATE");
            ota_upgrade_req_t *ota_req = (ota_upgrade_req_t *)parse_ota_update(root);
            if (ota_req)
            {
                if (0 != send_msg_to_mng(ota_req, OTA_UPGRADE_REQUEST))
                {
                    rt_free(ota_req);
                }
            }
            break;
        }
        case PROT_SCAN_FREQ_REQ:
        {
            TRACE_I("mqtt PROT_SCAN_FREQ_REQ");
            if (manager_get_scan_freq_state())
            {
                TRACE_W("scan freq state is busy, ignore scan freq request");
                break;
            }
            gw_scan_freq_req_t *scan_freq_req = (gw_scan_freq_req_t *)parse_scan_freq_request(root);
            if (scan_freq_req)
            {
                if (0 != send_msg_to_mng(scan_freq_req, GATEWAY_SCAN_FREQ_REQ))
                {
                    if (scan_freq_req->freq_list)
                    {
                        rt_free(scan_freq_req->freq_list);
                    }
                    rt_free(scan_freq_req);
                }
            }
            break;
        }
        default:
            TRACE_E("unknown cmd: %d", cmd);
            break;
        }
        // 释放 JSON
        cJSON_Delete(root);
        root = RT_NULL;
    }
    else
    {
        TRACE_E("json parse payload %s", mqtt_msg->payload);
    }

    // 释放 MQTT 消息
    release_mqtt_message(mqtt_msg);

    // MQTT 接收到数据后指示灯闪烁
    send_led_event(LED_MQTT, LED_E_BLINK);
}

/**
 * @brief  OTA 升级下载请求
 *
 * @param  ota ota 升级消息
 */
static void net_ota_upgrade_download(ota_upgrade_req_t *ota)
{
    // http 下载
    http_download(ota->http_info.address, ota->http_info.file_name, ota->ota_info.md5);
}

/**
 * @brief  OTA 升级完成消息
 *
 * @param  ota ota 升级消息
 */
static void net_ota_upgrade_completed(ota_upgrade_complete_t *cmp_info)
{
    net_publish(encode_ota_upgrade_complete_info(cmp_info));
}

static void idle_mqtt_state_hook(void)
{
    unsigned int abnormal_timeout = (uc_static_get_gateway_timed_cfg()->abnormal_time * 1000);

    rt_base_t level = rt_hw_interrupt_disable();
    //  MQTT 连接异常后，如果长时间连接不上，强制重启设备
    if (MQTT_STATE_ONLINE != manager_get_mqtt_state() &&
        0 != abnormal_timeout &&
        (~0) != g_mqtt_offline_time &&
        0 != g_mqtt_offline_time)
    {
        if ((rt_tick_get() > g_mqtt_offline_time && (rt_tick_get() - g_mqtt_offline_time > abnormal_timeout)) ||
            (rt_tick_get() < g_mqtt_offline_time) && ((~0) - g_mqtt_offline_time + rt_tick_get() > abnormal_timeout * RT_TICK_PER_SECOND))
        {
            rt_kprintf("mqtt abnormal timeout, reboot %x", g_mqtt_offline_time);
            rt_thread_mdelay(100);
            extern void watchdog_reboot(void);
            watchdog_reboot();
            // while (1)
            //     ;
        }
    }

    mqtt_push_checkout();

    rt_hw_interrupt_enable(level);
}

/**
 * @brief  网络状态改变回调函数
 *
 * @param  netdev 网络设备结构体
 * @param  type 网络状态
 */
static void netdev_status_changed_callback(struct netdev *netdev, enum netdev_cb_type type)
{
    int index = netdev_get_index_by_netdev(netdev);
    if (index >= 0)
    {
        TRACE_D("netdev %s status changed %d", netdev->name, type);
        if (NETDEV_CB_STATUS_LINK_UP == type ||
            NETDEV_CB_STATUS_LINK_DOWN == type ||
            NETDEV_CB_STATUS_INTERNET_UP == type ||
            NETDEV_CB_STATUS_INTERNET_DOWN == type)
        {
            netdev_set_net_status(index, type);
            if (RT_TRUE == g_net_status_change_send_flag)
            {
                notifice_netdev_change();
            }
        }
    }
    else
    {
        TRACE_E("netdev index not found");
    }
}

/**
 * @brief net_change_app 任务
 *
 * @param para 任务参数
 */
void net_change_app_task(void *para)
{
    module_queue_message_t *page;

    TRACE_I("net_change_app_task begin");

    netdev_set_status_changed_callback(netdev_status_changed_callback);

    netdev_reselect_policy(GATEWAY_WIFI_CONNECT);

    // 设置MQTT状态灯初始状态为常亮
    send_led_event(LED_MQTT, LED_E_EXCEPTION);

    // 启动 MQTT
    mqtt_start();

    rt_thread_idle_sethook(idle_mqtt_state_hook);

    g_net_status_change_send_flag = RT_TRUE;

    while (1)
    {
        if (QUEUE_EOK != manager_recv_queue(g_net_change_app_queue, (void *)&page, UC_QUEUE_WAITING_FOREVER))
        {
            continue;
        }

        switch (page->cmd)
        {
        case NETDEV_CHANGE_CMD:
            TRACE_I("net NETDEV_CHANGE_CMD");
            netdev_reselect_policy(GATEWAY_NET_RESELECT);
            break;
        }

        // 释放内存
        if (RT_NULL != page)
        {
            if (RT_NULL != page->data)
            {
                rt_free(page->data);
                page->data = RT_NULL;
            }
            rt_free(page);
            page = RT_NULL;
        }
    }
}

/**
 * @brief net_app 任务
 *
 * @param para 任务参数
 */
void net_app_task(void *para)
{
    void *net_passthrough_handle = RT_NULL;
    module_queue_message_t *page;

    TRACE_I("net_app_task begin");

    // 创建net app队列
    net_change_app_create_queue();

    // 创建net app任务
    if (0 != manager_thread_create(&net_passthrough_handle, "net_change_app", net_change_app_task, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX - 5, 5))
    {
        TRACE_E("net_change_app task create error");
        return;
    }

    rt_thread_startup((rt_thread_t)net_passthrough_handle);

    while (RT_TRUE != g_net_status_change_send_flag)
    {
        rt_thread_mdelay(100);
    }

    while (1)
    {
        if (QUEUE_EOK != manager_recv_queue(g_net_app_queue, (void *)&page, UC_QUEUE_WAITING_FOREVER))
        {
            continue;
        }
        // TRACE_I("net_app_task 0x%x", page->cmd);

        switch (page->cmd)
        {
        case NET_IOTE_STATE_UPDATE:
            TRACE_I("net NET_IOTE_STATE_UPDATE");
            net_iote_state_update((void *)page->data);
            break;
        case NET_IOTE_VERSION_RES:
            TRACE_I("net NET_IOTE_VERSION_RES");
            net_iote_version_res((void *)page->data);
            break;
        case NET_IOTE_USER_DATA:
            TRACE_I("net NET_IOTE_USER_DATA");
            net_iote_user_data((void *)page->data);
            break;
        case NET_OTA_DOWNLOAD_REQUEST:
            TRACE_I("net NET_OTA_DOWNLOAD_REQUEST");
            net_ota_upgrade_download((ota_upgrade_req_t *)page->data);
            break;
        case NET_OTA_UPGRADE_COMPLETE:
            TRACE_I("net NET_OTA_UPGRADE_COMPLETE");
            net_ota_upgrade_completed((ota_upgrade_complete_t *)page->data);
            break;
        case NET_MQTT_STATE_CHANGED:
            TRACE_I("net NET_MQTT_STATE_CHANGED");
            net_mqtt_state_changed((int)page->data);
            // 不需要释放内存
            page->data = RT_NULL;
            break;
        case NET_MQTT_RECV_MESSAGE:
            TRACE_I("net NET_MQTT_RECV_MESSAGE");
            net_mqtt_recv_msg((net_mqtt_message_t *)page->data);
            break;
        case WIOAT_VERSION_GET:
            TRACE_I("net WIOAT_VERSION_GET");
            net_publish(encode_wiota_version(page->data));
            break;
        case WIOTA_SYS_CFG_GET:
            TRACE_I("net WIOTA_SYS_CFG_GET");
            net_publish(encode_wiota_sys_cfg(page->data));
            break;
        case WIOTA_ACT_CFG_GET:
            TRACE_I("net WIOTA_ACT_CFG_GET");
            net_publish(encode_wiota_act_cfg(page->data));
            break;
        case WIOTA_FREQ_CFG_GET:
            TRACE_I("net WIOTA_FREQ_CFG_GET");
            net_publish(encode_wiota_freq_cfg(page->data));
            break;
        case WIOTA_POWER_CFG_GET:
            TRACE_I("net WIOTA_POWER_CFG_GET");
            net_publish(encode_wiota_power_cfg(page->data));
            break;
        case WIOTA_RATE_CFG_GET:
            TRACE_I("net WIOTA_RATE_CFG_GET");
            net_publish(encode_wiota_rate_cfg(page->data));
            break;
        case WIOTA_PAGING_TX_CFG_GET:
            TRACE_I("net WIOTA_PAGING_TX_CFG_GET");
            net_publish(encode_wiota_paging_tx_cfg(page->data));
            break;
        case WIOTA_SYNC_PAGING_CFG_GET:
            TRACE_I("net WIOTA_SYNC_PAGING_CFG_GET");
            net_publish(encode_wiota_sync_paging_cfg(page->data));
            break;
        case WIOTA_TS_CFG_GET:
            TRACE_I("net WIOTA_TS_CFG_GET");
            net_publish(encode_wiota_ts_cfg(page->data));
            break;
#ifdef WIOTA_SUBF_MODE_SUPPORT
        case WIOTA_SUBF_MODE_CFG_GET:
            TRACE_I("net WIOTA_SUBF_MODE_CFG_GET");
            net_publish(encode_wiota_subf_mode_cfg(page->data));
            break;
#endif
        case GATEWAY_BASE_CFG_GET:
            TRACE_I("net GATEWAY_BASE_CFG_GET");
            net_publish(encode_gateway_base_cfg(page->data));
            break;
        case ID_MANAGER_CFG_GET:
            TRACE_I("net ID_MANAGER_CFG_GET");
            net_publish(encode_gateway_id_mng_cfg(page->data));
            break;
        case AUTH_CFG_GET:
            TRACE_I("net AUTH_CFG_GET");
            net_publish(encode_gateway_auth_cfg(page->data));
            break;
        case NET_CFG_GET:
            TRACE_I("net NET_CFG_GET");
            net_publish(encode_gateway_net_cfg(page->data));
            break;
        case NET_POLICY_CFG_GET:
            TRACE_I("net NET_POLICY_CFG_GET");
            net_publish(encode_gateway_net_policy_cfg(page->data));
            break;
        case NET_IF_CFG_GET:
            TRACE_I("net NET_IF_CFG_GET");
            net_publish(encode_gateway_net_if_cfg(page->data));
            break;
        case WIFI_CFG_GET:
            TRACE_I("net WIFI_CFG_GET");
            net_publish(encode_gateway_wifi_cfg(page->data));
            break;
        case CAT1_CFG_GET:
            TRACE_I("net CAT1_CFG_GET");
            net_publish(encode_gateway_cat1_cfg(page->data));
            break;
        case BT_CFG_GET:
            TRACE_I("net BT_CFG_GET");
            net_publish(encode_gateway_bt_cfg(page->data));
            break;
        case MQTT_SERVER_CFG_GET:
            TRACE_I("net MQTT_SERVER_CFG_GET");
            net_publish(encode_gateway_mqtt_cfg(page->data));
            break;
        case DATA_CFG_GET:
            TRACE_I("net DATA_CFG_GET");
            net_publish(encode_gateway_data_cfg(page->data));
            break;
        case WATCHDOG_CFG_GET:
            TRACE_I("net WATCHDOG_CFG_GET");
            net_publish(encode_gateway_wtd_cfg(page->data));
            break;
        case GATEWAY_FTP_LOG_CFG_GET:
            TRACE_I("net GATEWAY_FTP_LOG_CFG_GET");
            net_publish(encode_gateway_ftp_log_cfg(page->data));
            break;
        case LOG_SWITCH_CFG_GET:
            TRACE_I("net LOG_SWITCH_CFG_GET");
            net_publish(encode_gateway_log_switch_cfg(page->data));
            break;
        case UART_485_CFG_GET:
            TRACE_I("net UART_485_CFG_GET");
            net_publish(encode_gateway_uart_485_cfg(page->data));
            break;
        case SLOT_SEND_CFG_GET:
            TRACE_I("net SLOT_SEND_CFG_GET");
            net_publish(encode_slot_send_cfg(page->data));
            break;
        case ALL_CFG_GET:
            TRACE_I("net ALL_CFG_GET");
            do
            {
                char *json_str = encode_gateway_all_cfg();
                if (RT_NULL != json_str)
                    net_publish(json_str);
                else
                    break;
            } while (1);
            TRACE_I("report gateway_all_cfg suc");
            break;
        case UBOOT_CFG_GET:
            TRACE_I("net UBOOT_CFG_GET");
            net_publish(encode_uboot_cfg(page->data));
            break;
        case IMMEDIATE_EFFECTIVE_GET:
            TRACE_I("net IMMEDIATE_EFFECTIVE_GET");
            net_publish(encode_immediate_effective_cfg(page->data));
            break;
        case FACTORY_TEST_RESULT_GET:
            TRACE_I("net FACTORY_TEST_RESULT_GET");
            net_publish(encode_factory_test_result_cfg(page->data));
            break;
        case GATEWAY_TIMED_CFG_GET:
            TRACE_I("net GATEWAY_TIMED_CFG_GET");
            net_publish(encode_gateway_timed_cfg(page->data));
            break;
        case NET_SEND_TRANSPARENT_DATA:
            TRACE_I("net NET_SEND_TRANSPARENT_DATA");
            net_publish(encode_transparent_data(page->data));
            break;
        case SYNC_CFG_GET:
            TRACE_I("net SYNC_CFG_GET");
            net_publish(encode_sync_cfg(page->data));
            break;
        case DEVICE_STATUS_GET:
            TRACE_I("net DEVICE_STATUS_GET");
            net_publish(encode_device_status(page->data));
            break;

        case GATEWAY_AUTH_LIST_GET:
        {
            TRACE_I("net GATEWAY_AUTH_LIST_GET");
            int is_over = 0;
            do
            {
                char *json_str = encode_gateway_auth_list(page->data, &is_over);
                if (RT_NULL != json_str)
                    net_publish(json_str);
                if (is_over)
                    break;
            } while (1);
            break;
        }

        case SYNC_DYNAMICS_INFO_GET:
            TRACE_I("net SYNC_DYNAMICS_INFO_GET");
            net_publish(encode_sync_dynamics_info(page->data));
            break;

        case GATEWAY_SCAN_FREQ_REQ:
        {
            TRACE_I("net GATEWAY_SCAN_FREQ_REQ");
            int is_over = 0;
            do
            {
                char *json_str = encode_gateway_scan_resp(page->data, &is_over);
                if (RT_NULL != json_str)
                    net_publish(json_str);
                if (is_over)
                    break;
            } while (1);
            break;
        }

        default:
            break;
        }
        // 释放内存
        if (RT_NULL != page)
        {
            if (RT_NULL != page->data)
            {
                rt_free(page->data);
                page->data = RT_NULL;
            }
            rt_free(page);
            page = RT_NULL;
        }
    }
}
